import {expect} from '@jest/globals';
import {iconv} from '@ohos/hvigor';
import * as execa from 'execa';
import fse from 'fs-extra';
import path from 'path';

import {initExecuteCommand, runHvigorAsync} from '../../common/common';
import {buildOneHapAndCheckFile, resourcesPath} from '../../plugins//common-fun';
import {commonConfig} from '../../plugins/common-config';
import {
  AbilityType,
  APIType,
  APIVersion,
  CaseLevel,
  LanguageType,
  ModuleTemplateType,
  RuntimeOSType,
  SDKType
} from '../../plugins/project-builder/models/constants';
import {Project} from '../../plugins/project-builder/models/project-models';
import {ICaseRecord} from '../../plugins/report-builder/report-models';
import {TestCaseBuilder} from '../../plugins/task-builder/task-case-builder';
import {ProjectBuildOption, TestCaseFun} from '../../plugins/task-builder/test-case';
import {TestTaskOptionBuilder} from '../../plugins/task-builder/test-task-option';

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: APIVersion.API10,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.ListAbility
  }
};

async function buildLibrary(project:Project, record: ICaseRecord) {
  const projectRootPath = project.projectRootPath();
  const libraryPath = path.resolve(projectRootPath, 'staticlibrary');
  const entryPath = project.getModule('entry').moduleRootPath();
  await fse.copy(path.resolve(resourcesPath, 'extra/staticlibrary'), libraryPath);
  const moduleFile = await fse.readFile(`${projectRootPath}/build-profile.json5`);

  // 去掉文件中多余的 ,
  const str = iconv.decode(moduleFile, 'utf-8').replace(/(,[\r\n]\s+[}|\]])/g, ($1) => $1.slice(1));

  const moduleObj = JSON.parse(str);
  moduleObj.modules.push({
    name: 'test_stage_ets_library',
    srcPath: './staticlibrary',
  });
  await fse.writeFile(`${projectRootPath}/build-profile.json5`, JSON.stringify(moduleObj, null, 2), 'utf-8');
  const libraryMain = path.resolve(libraryPath, 'src/main');
  await fse.ensureFile(`${libraryMain}/module.json5`);
  await fse.writeFile(`${libraryMain}/module.json5`, JSON.stringify({
    module: {
      name: 'test_stage_ets_library',
      type: 'har',
      deviceTypes: [
        'phone',
        'tablet'
      ]
    }
  }, null, 2), 'utf-8');

  const library = await runHvigorAsync(projectRootPath, initExecuteCommand({
    mode: 'module',
    product: 'default',
    tasks: 'assembleHar',
    module: 'test_stage_ets_library'
  }));

  record.addStep('编译library', library);

  // 打包library
  const libraryHar = path.resolve(libraryPath, 'build', 'default', 'outputs', 'default', 'test_stage_ets_library.har');
  const existsHar = await fse.pathExists(libraryHar);
  expect(existsHar).toBe(true);

  // 将library.har复制到entry，并在json5中添加依赖
  await fse.copyFile(libraryHar, `${entryPath}/test_stage_ets_library.har`);
  const jsonPath = path.resolve(entryPath, 'oh-package.json5');
  const jsonBuffer = await fse.readFile(jsonPath);
  const jsonData = JSON.parse(iconv.decode(jsonBuffer, 'utf-8'));
  jsonData.dependencies['@ohos/test_stage_ets_library'] = 'file:test_stage_ets_library.har';
  await fse.writeFile(jsonPath, JSON.stringify(jsonData,null,2), 'utf-8');

  // 执行ohpm install
  const install = await execa.command(commonConfig.ohpmInstallCommand, {
    cwd: entryPath
  });
  record.addStep('entry install', install);
}

const testFun: TestCaseFun = async (project, taskConfig, record) => {
  const entryPath = project.getModule('entry').moduleRootPath();
  await buildLibrary(project, record);

  // 3.entry模块依赖ohos共享模块中的string或者图片资源
  const fileData = await fse.readFile(path.resolve(entryPath, 'src/main/ets/viewmodel/PageViewModel.ets'));
  const fileStr = iconv.decode(fileData, 'utf-8').replace('list_item_summary', 'page_show');
  await fse.writeFile(path.resolve(entryPath, 'src/main/ets/viewmodel/PageViewModel.ets'), fileStr, 'utf-8');

  await buildOneHapAndCheckFile('entry')(project, taskConfig, record);
};

const componentsTestFun: TestCaseFun = async (project, taskConfig, record) => {
  const entryPath = project.getModule('entry').moduleRootPath();
  await buildLibrary(project, record);

  const listPage = path.resolve(entryPath, 'src/main/ets/pages/ListPage.ets');

  // 4、在entry模块的index.ets文件中进行ets components引用
  const fileData = await fse.readFile(listPage);
  const fileStr = iconv.decode(fileData, 'utf-8').replace('ForEach(PageViewModel.getTabData()', `TabContent() {
          MainPage()
        }.tabBar('首页')
        ForEach(PageViewModel.getTabData()`);
  await fse.writeFile(listPage, `import { MainPage } from '@ohos/test_stage_ets_library';\n  ${fileStr}`, 'utf-8');

  await buildOneHapAndCheckFile('entry')(project, taskConfig, record);
};

TestCaseBuilder.builder()
  .caseName('OPENLAB_AIDE_ZOS_Build_Entry_Shared_Modules_HOS_api10_STAGE_003')
  .description('3.新模型工程entry-stage-eTS引用本地ets+ohpm包资源')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(TestTaskOptionBuilder.builder().caseLevel(CaseLevel.L1).build())
  .testFun(testFun)
  .load();


TestCaseBuilder.builder()
  .caseName('OPENLAB_AIDE_ZOS_Build_library_Dependence_HOS_api10_STAGE_003')
  .description('003、eTS工程，entry模块依赖ets共享模块_ets引用')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(TestTaskOptionBuilder.builder().caseLevel(CaseLevel.L1).build())
  .testFun(componentsTestFun)
  .load();